package com.chen.seckill.service.impl;

import com.chen.seckill.dao.ItemMapper;
import com.chen.seckill.dao.ItemStockMapper;
import com.chen.seckill.error.BusinessException;
import com.chen.seckill.error.EmBusinessError;
import com.chen.seckill.pojo.Item;
import com.chen.seckill.pojo.ItemStock;
import com.chen.seckill.service.ItemService;
import com.chen.seckill.service.PromoService;
import com.chen.seckill.service.bo.ItemBO;
import com.chen.seckill.service.bo.PromoBO;
import com.chen.seckill.validator.ValidationResult;
import com.chen.seckill.validator.ValidatorImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    private ValidatorImpl validator;

    @Autowired
    private ItemMapper itemMapper;

    @Autowired
    private ItemStockMapper itemStockMapper;

    @Autowired
    private PromoService promoService;

    // 将ItemBO对象转换为Item对象
    private Item convertItemFromItemBO(ItemBO itemBO) {
        if (itemBO == null) {
            return null;
        }
        Item item = new Item();
        BeanUtils.copyProperties(itemBO, item);
        // BO和DO的数据类型不一致，需要手动转换
        item.setPrice(itemBO.getPrice().doubleValue());

        return item;
    }

    // 将ItemBO对象转化为ItemStock对象
    private ItemStock convertItemStockFromItemBO(ItemBO itemBO) {
        if (itemBO == null) {
            return null;
        }
        ItemStock itemStock = new ItemStock();

        itemStock.setItemId(itemBO.getId());
        itemStock.setStock(itemBO.getStock());

        return itemStock;
    }

    @Override
    @Transactional
    public ItemBO createItem(ItemBO itemBO) throws BusinessException {
        // 校验入参
        ValidationResult result = validator.validate(itemBO);
        if (result.isHasError()) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, result.getErrMsg());
        }

        // 转化itemBO到DO
        Item item = this.convertItemFromItemBO(itemBO);

        // 写入数据库
        itemMapper.insertSelective(item);
        // 设置id方便下面itemStock中的item_id和item中的id一致
        itemBO.setId(item.getId());

        ItemStock itemStock = convertItemStockFromItemBO(itemBO);
        itemStockMapper.insertSelective(itemStock);

        //返回创建完成的对象

        return this.getItemById(itemBO.getId());
    }

    @Override
    public List<ItemBO> listItem() {
        List<Item> itemList = itemMapper.listItem();
        List<ItemBO> itemBOList = itemList.stream().map(item -> {
            ItemStock itemStock = itemStockMapper.selectByItemId(item.getId());
            ItemBO itemBO = this.convertBOFromDO(item, itemStock);
            return itemBO;
        }).collect(Collectors.toList());
        return itemBOList;
    }

    @Override
    public ItemBO getItemById(Integer id) {
        Item item = itemMapper.selectByPrimaryKey(id);
        if (item == null) {
            return null;
        }
        //获得库存数量
        ItemStock itemStock = itemStockMapper.selectByItemId(item.getId());

        // 将DO转化为BO
        ItemBO itemBO = convertBOFromDO(item, itemStock);

        // 获取活动商品信息。如果聚合模型秒杀活动存在，并且状态不为3（已结束），则将秒杀活动信息赋给商品
        PromoBO promoBO = promoService.getPromoByItemId(itemBO.getId());
        if (promoBO != null && promoBO.getStatus() != 3) {
            itemBO.setPromoBO(promoBO);
        }

        return itemBO;
    }

    @Override
    @Transactional// 减操作，设计业务一致性
    public boolean decreaseStock(Integer itemId, Integer amount) throws BusinessException {
        int affectedRow = itemStockMapper.decreaseStock(itemId, amount);
        if (affectedRow > 0) {
            // 更新库存成功
            return true;
        } else {
            // 更新库存失败
            return false;
        }
    }

    // 商品销量增加
    @Override
    @Transactional
    public void increaseSales(Integer itemId, Integer amount) throws BusinessException {
        itemMapper.increaseSales(itemId, amount);
    }

    // 将Item和ItemStock转化为ItemBO
    private ItemBO convertBOFromDO(Item item, ItemStock itemStock) {
        ItemBO itemBO = new ItemBO();
        BeanUtils.copyProperties(item, itemBO);
        // 将double转化为BigDecimal
        itemBO.setPrice(BigDecimal.valueOf(item.getPrice()));
        itemBO.setStock(itemStock.getStock());

        return itemBO;
    }
}
